package com.zxc.ompz;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;

public class MediaField extends Field {
	/** A flag to debug **/
	private boolean debug;
	private boolean focused = false;
	
	/** field **/
	private int x=0;
	private int y=0;
	private int width = Display.getWidth();
	private int height = 104;
	/** main ui margin from screen border **/
	private int marginX = 2;
	private int marginY = 2;
	/** main internal field margin from main ui **/
	private int marginIX = 22;
	private int marginIY = 22;
	/** title **/
	int xTitle = x+marginX+marginIX;
	int yTitle = y+marginY+marginIY/2;
	int widthTitle = 124;
	/** name **/
	private int xName = xTitle+widthTitle;
	private int yName = yTitle;
	private int widthName = width-2*marginX-2*marginIX-widthTitle;
	/** button **/
	int xButton = x+marginX+marginIX;
	int yButton = y+marginY+marginIY;
	private int widthButton = 56;
	private int heightButton = 56;
	/** bitmap */
	private int widthBmp = 48;
	private int heightBmp = 48;
	private int xBmp = xButton+(widthButton-widthBmp)/2;
	private int yBmp = yButton+(heightButton-heightBmp)/2;
	/** bar **/
	private int xBar = xButton+widthButton+6;
	private int yBar = yButton;
	private int widthBar = width-2*marginX-2*marginIX-widthButton-6;
	private int heightBar = heightButton;
	/** buffer **/
	private int xBuffer = xBar+1;
	private int yBuffer = yBar+1;
	private int widthBuffer;
	private int heightBuffer = heightBar-2;
	/** timer  **/
	private int xTimer = xBar+1;
	private int yTimer = yBar+1;
	private int widthTimer;
	private int heightTimer = heightBar-2;
	/** digit timer **/
	private int xDigitTimer = xBar+12;
	private int yDigitTimer = yBar+heightBar/2;
	private int widthDigitTimer = widthBar-24;
	/** type **/
	private int xType = xBar;
	private int yType = yBar;
	private int widthType = widthBar;
	/** volume **/
	private int xVolume = xButton;
	private int yVolume = yButton+heightButton+marginIY/2;
	private int widthVolume = 100;
	private int widthVolumeBmp = 16;
	private int heightVolumeBmp = 16;
	/** event **/
	private int xEvent = xBar+widthBar/2;
	private int yEvent = yVolume;
	private int widthEvent = widthBar/2;
	
	/** buffer postion **/
	private long resv;
	private long tail;
	private long head;	
	/** time and size ratio **/
	private double ratioTime=0;
	private double ratioSize=0;
	
	private long now;
	private boolean pause = true;
	private String name;
	private String type;
	private long duration;
	private long length;
	private String event = "READY";
	private Bitmap bmpPlayer;
	private Bitmap bmpSpeaker;
	private int volumeLevel=75;
	
	private Font font1 = Font.getDefault().derive(Font.ITALIC|Font.BOLD, 18);
	private Font font2 = Font.getDefault().derive(Font.ITALIC|Font.BOLD, 16);
	private Font font3 = Font.getDefault().derive(Font.ITALIC, 16);
	private Font font4 = Font.getDefault().derive(Font.BOLD, 24);
	
	public MediaField()	{
		super(Field.FIELD_TOP|Field.FIELD_LEFT);
		bmpPlayer = Bitmap.getBitmapResource("player.png");
		bmpSpeaker = Bitmap.getBitmapResource("speaker.png");
	}
	public void setDebug(boolean debug){
		this.debug = debug;
	}
	public void setPause(boolean pause){
		this.pause = pause;
		invalidate(xButton, yButton, widthButton, heightButton);
	}
	public void setMediaName(String name){
		this.name = name;
		invalidate();
	}
	public void setMediaDuration(long duration){
		this.duration = duration;
		if (duration==0){
			ratioTime=0;
		}
		else{
			ratioTime = ((double)(widthBar-2))/(double)(duration);
		}
	}
	public void setMediaLength(long length){
		this.length = length;
		ratioSize = (double)(widthBar-2)/(double)this.length;
	}
	public void setMediaType(String type){
		this.type = type;
	}
	public void setBuffer(long[] positions){
		resv = positions[0];
		tail = positions[1];
		head = positions[2];
		invalidate(xBar, yBar, widthBar, heightBar);
	}
	public void setTimer(long now){
		this.now = now;
		invalidate(xBar, yBar, widthBar, heightBar);
	}
	public void setEvent(String event){
		this.event = event;
		invalidate(x, yButton+heightBar, width, marginIY);
	}
	public void setVolumeLevel(int level){
		this.volumeLevel = level;
		invalidate(x, yButton+heightBar, width, marginIY);
	}
	protected void layout(int width, int height){
		setExtent(this.width, this.height);
	}
	protected void paint(Graphics g){
		// Draw background
		if (focused){
			g.setColor(0x088AEF);
		}
		else{
			g.setColor(Color.WHITE);
		}
		g.fillRect(x, y, width, height);
		// Draw main ui
		g.setColor(11920925);
		g.fillRoundRect(x+marginX, y+marginY, width-2*marginX, height-2*marginY, 20, 20);
		// Draw title
		g.setColor(Color.WHITE);
		g.setFont(font1);
		g.drawText("OMPlayer", xTitle, yTitle, DrawStyle.LEFT | DrawStyle.VCENTER, widthTitle);
		paintName(g);
		paintButton(g);
		paintBar(g);
		paintBuffer(g);
		paintTimer(g);
		paintType(g);
		paintVolume(g);
		paintEvent(g);
	}
	private void paintName(Graphics g){
		// Draw filename
		g.setColor(Color.WHITE);
		g.setFont(font3);
		g.drawText(name, xName, yName, DrawStyle.RIGHT | DrawStyle.VCENTER, widthName);
	}
	private void paintButton(Graphics g){
		// Draw button
		g.setColor(Color.WHITE);
		g.fillRect(xButton, yButton, widthButton, heightButton);
		if(focused){
			g.setColor(0x088AEF);
			g.drawRoundRect(xButton, yButton, widthButton, heightButton, 4, 4);
		}
		if (pause){
			g.drawBitmap(xBmp, yBmp, widthBmp, heightBmp, bmpPlayer, 48, 0);
		}
		else{
			g.drawBitmap(xBmp, yBmp, widthBmp, heightBmp, bmpPlayer, 0, 0);
		}
	}
	private void paintBar(Graphics g){
		// Draw bar
		g.setColor(Color.WHITE);
		g.fillRect(xBar, yBar, widthBar, heightBar);
	}
	private void paintBuffer(Graphics g){
		int resv = (int)(this.resv*ratioSize);
		int tail = (int)(this.tail*ratioSize);
		int head = (int)(this.head*ratioSize);
		// Draw buffer
		xBuffer = xBar+1+resv;
		yBuffer = yBar+1;
		widthBuffer = head-resv;
		heightBuffer = heightBar-2;		//minus 2 for margin
		g.setColor(Color.GRAY);
		g.setGlobalAlpha(64);
		g.fillRect(xBuffer, yBuffer, widthBuffer, heightBuffer);
		g.setGlobalAlpha(255);
		if (debug){
			String buffer = this.resv+":"+this.tail+":"+this.head;
			g.setColor(Color.BLACK);
			g.setFont(font1);
			g.drawText(buffer, xBar, yBar+heightBar, DrawStyle.RIGHT | DrawStyle.BOTTOM, widthBar);
		}
	}
	private void paintTimer(Graphics g){
		widthTimer = (int)(now*ratioTime);
		g.setColor(0x088AEF);
		g.setGlobalAlpha(192);
		g.fillRect(xTimer, yTimer, widthTimer, heightTimer);
		g.setGlobalAlpha(255);
		
		g.setColor(11920925);
		g.setFont(font4);
		String s1 = new Timer(now).toString();
		String s2 = new Timer(duration).toString();
		g.drawText(s1, xDigitTimer, yDigitTimer, DrawStyle.LEFT | DrawStyle.VCENTER);
		g.drawText(s2, xDigitTimer, yDigitTimer, DrawStyle.RIGHT| DrawStyle.VCENTER, widthDigitTimer);
	}
	private void paintType(Graphics g){
		if (debug){
			g.setColor(Color.BLACK);
			g.setFont(font2);
			g.drawText(type+"("+length+")", xType, yType, DrawStyle.RIGHT | DrawStyle.TOP, widthType);
		}
	}
	private void paintVolume(Graphics g){
		if (volumeLevel>0){
			g.drawBitmap(xVolume, yVolume-widthVolumeBmp/2, widthVolumeBmp, heightVolumeBmp, bmpSpeaker, 0, 0);
		}
		else{
			g.drawBitmap(xVolume, yVolume-widthVolumeBmp/2, widthVolumeBmp, heightVolumeBmp, bmpSpeaker, 16, 0);
		}
		g.setColor(Color.WHITE);
		g.drawRoundRect(xVolume+widthVolumeBmp+2, yVolume-2, widthVolume, 4, 5, 5);		
		g.fillRoundRect(xVolume+widthVolumeBmp+2, yVolume-2, volumeLevel, 4, 5, 5);
	}
	private void paintEvent(Graphics g){
		// Draw player event
		g.setColor(Color.WHITE);
		g.setFont(font2);
		g.drawText(event, xEvent, yEvent, DrawStyle.RIGHT | DrawStyle.VCENTER, widthEvent);
	}
	protected void onFocus(int direction){
		focused = true;
		super.onFocus(direction);
		invalidate();
	}
	protected void onUnfocus(){
		focused = false;
		super.onUnfocus();
		invalidate();
	}
	public boolean isFocusable(){
		return true;
	}
}
